<?php

class Controller
{

    /**
     * @var Request
     */
    protected $_request;

    /**
     * @var string
     */
    protected $_actionName = 'index';

    /**
     * @var string|array
     */
    protected $_scripts = null;

    /**
     * mark is no render
     * @var bool
     */
    protected $_noRender = false;

    /**
     * constructor
     * @param Request $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this -> _request = $request;
        $this -> init();
    }

    /**
     * check is no render
     * @return bool
     */
    public function isNoRender()
    {
        return $this -> _noRender;
    }

    /**
     * @param bool $flag
     * @return Controller
     */
    public function setNoRender($flag = true)
    {
        $this -> _noRender = (bool)$flag;
    }

    /**
     * @return Request
     */
    public function getRequest()
    {
        return $this -> _request;
    }

    /**
     * @param Request $request
     * @return Controller
     */
    public function setRequest(Request $request)
    {
        $this -> _request = $request;
        return $this;
    }

    /**
     * action
     * @param string $action
     * @return Controller
     */
    public function setActionName($action)
    {
        $this -> _actionName = $action;
        return $this;

    }

    /**
     * @return string
     */
    public function getActionName()
    {
        return $this -> _actionName;
    }

    public function init()
    {

    }

    /**
     * @param string|array $scripts
     * @return Controller
     */
    public function setScripts($scripts)
    {
        $this -> _scripts = $scripts;
        return $this;
    }

    /**
     * @return array|string
     */
    public function getScripts()
    {
        if (null == $this -> _scripts)
        {
            $this -> _scripts = implode('/', array_map('nuo_deflect_string', explode('_', str_replace('_Controller_', '_views_', get_class($this))))) . '/' . $this -> _actionName . '.tpl';
        }
        return $this -> _scripts;
    }

    /**
     * check action.
     * @param string $action
     * @return void
     * @throws Nuo_Exception
     */
    public function dispatch($action = 'index')
    {
        /**
         * reset action name
         */
        $this -> _actionName = $action;

        $method = Nuo::getActionMethod($this -> _actionName);

        if (!method_exists($this, $method))
        {
            throw new Nuo_Exception("[" . get_class($this) . "] has no action [$method]!");
        }

        $this -> _request -> setDispatched(1);
        $this -> {$method}();
    }

    /**
     * forward to other action/controller
     * @return Controller
     */
    protected function _forward($action, $controllerName = null)
    {
        if (null != $controllerName)
        {
            $this -> _request -> setController(null) -> setControllerName($controllerName);
        }
        $this -> _request -> setDispatched(0) -> setActionName($action);
        return $this;
    }

    public function render($data = null, $scripts = null)
    {
        if (null == $data)
        {
            $data = $this;
        }

        if (null == $scripts)
        {
            $scripts = $this -> getScripts();
        }

        return View::render($data, $scripts);
    }

}
